#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "pcap.h"
#include <QDebug>
#include "winsock2.h"
#include <QStringList>
#include <QColor>
#include <QMessageBox>
#include <QTreeWidgetItem>
#include "multhread.h"

// 构造函数，初始化主窗口和 UI
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 显示网络接口卡信息
    statusBar()->showMessage("welcome to shark!");
    // 设置工具栏
    ui->toolBar->addAction(ui->actionrunandstop);
    ui->toolBar->addAction(ui->actionclear);
    ui->toolBar->addAction(ui->actionup);
    ui->toolBar->addAction(ui->actiondown);
    ui->toolBar->addAction(ui->actionTop);
    ui->toolBar->addAction(ui->actionEnd);
    countNumber = 0;
    numberRow = -1;
    // 显示网卡
    showNetworkCard();
    // 创建一个线程对象
    multhread *thread = new multhread;
    ui->comboBox->setEnabled(true);
    isStart = false;
    // 设置一个布尔值，用于控制捕获数据包的开始和停止
    static bool index = false;
    countNumber = 0;
    numberRow = -1;
    pData.clear();
    device = nullptr;
    pointer = nullptr;
     // 添加信号槽
    connect(ui->actionrunandstop, &QAction::triggered, this,[=](){
        index = !index;
        if(index){

            ui->tableWidget->clearContents();
            ui->tableWidget->setRowCount(0);
            countNumber = 0;
            numberRow = -1;

            int dataSize = this->pData.size();
            for(int i = 0; i < dataSize;i++){
                free((char*)(this->pData[i].pkt_content));
                this->pData[i].pkt_content = nullptr;
            }
            QVector<Datapackage>().swap(pData);
            // 开始捕获数据包
            int res = capture();
            if(res != -1 && pointer){
                // 启动线程，将捕获的数据包指针传递给线程
                thread->setPointer(pointer);
                thread->setFlag();
                thread->start();
                // 切换动作图标
                ui->actionrunandstop->setIcon(QIcon(":/stop.png"));
                // 禁用选择网络接口卡的下拉框
                ui->comboBox->setEnabled(false);
            }else{ // 启动失败
                index = !index;
                countNumber = 0;
                numberRow = -1;
                isStart = false;
            }
        }
        else{
            // 停止捕获数据包
            thread->resetFlag();
            thread->quit();
            thread->wait();
             // 换动作图标
            ui->actionrunandstop->setIcon(QIcon(":/start.png"));
             // 启动选择网络接口卡的下拉框
            ui->comboBox->setEnabled(true);
             // 关闭数据包捕获句柄
            pcap_close(pointer);
            pointer = nullptr;
            // 结束
        }
    });


    // 连接 "清空" QAction 的触发信号到一个 Lambda 函数
    connect(ui->actionclear, &QAction::triggered, this, [=]{
        // 检查应用程序是否处于 "开始" 状态
        if (!isStart) {
            // 如果不是，显示一个消息框，询问用户是否要清空所有数据
            int type = QMessageBox::information(this, "信息", "是否要清空所有数据？", "是", "取消");
            if (type == 0) { // 如果用户选择了 "是"
                // 清空表格和树形视图中的所有内容
                ui->tableWidget->clearContents();
                ui->tableWidget->setRowCount(0);
                ui->treeWidget->clear();
                countNumber = 0; // 重置计数器
                numberRow = -1;
                int pDataSize = this->pData.size();
                // 释放数据包中的内存，并将指针设置为空
                for (int i = 0; i < pDataSize; i++) {
                    free((char*)(this->pData[i].pkt_content));
                    this->pData[i].pkt_content = nullptr;
                }
                // 清空数据包数组
                QVector<Datapackage>().swap(pData);
            } else {
                // 如果用户选择了 "取消"，则返回
                return;
            }
        }
    });


    // 连接 "上移" QAction 的触发信号到一个 Lambda 函数
    connect(ui->actionup, &QAction::triggered, this, [=]{
        // 获取当前选择的行的索引
        int index = ui->tableWidget->currentRow();
        // 如果当前行不是第一行，则上移一行
        if (index > 0) {
            ui->tableWidget->setCurrentCell(index - 1, 0);
            // 触发单元格点击事件
            on_tableWidget_cellClicked(index - 1, 0);
        } else {
            // 如果当前行已经是第一行，则返回
            return;
        }
    });


    connect(ui->actiondown,&QAction::triggered,this,[=]{
    int index = ui->tableWidget->currentRow();
    if(index >= 0 && index < ui->tableWidget->rowCount() - 1){
        ui->tableWidget->setCurrentCell(index + 1,0);
        on_tableWidget_cellClicked(index + 1,0);
    }else return;
});

    // 连接 "移到顶部" QAction 的触发信号到一个 Lambda 函数
    connect(ui->actionTop, &QAction::triggered, this, [=]{
        // 获取当前选择的行的索引
        int index = ui->tableWidget->currentRow();
        // 如果当前行不是第一行，则移到顶部
        if (index > 0) {
            ui->tableWidget->setCurrentCell(0, 0);
            // 触发单元格点击事件
            on_tableWidget_cellClicked(0, 0);
        } else {
            // 如果当前行已经是第一行，则返回
            return;
        }
    });


    // 连接 "移到底部" QAction 的触发信号到一个 Lambda 函数
    connect(ui->actionEnd, &QAction::triggered, this, [=]{
        // 获取表格行数，减去 1 是因为行索引是从 0 开始的
        int index = ui->tableWidget->rowCount() - 1;
        // 如果表格不为空，则移到底部
        if (index > 0) {
            ui->tableWidget->setCurrentCell(index, 0);
            // 触发单元格点击事件
            on_tableWidget_cellClicked(index, 0);
        }
    });


    // 连接线程的信号与槽函数
    connect(thread, &multhread::send, this, &MainWindow::HandleMessage);

    ui->tableWidget->setShowGrid(false);
    ui->toolBar->setMovable(false);
    ui->tableWidget->setColumnCount(7);
    readOnlyDelegate = new ReadOnlyDelegate();
    ui->tableWidget->setItemDelegate(readOnlyDelegate);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(30);
    QStringList title = {"NO.", "Time", "Source", "Destination", "Protocol", "Length", "Info"};
    ui->tableWidget->setHorizontalHeaderLabels(title);

    ui->tableWidget->setColumnWidth(0,50);
    ui->tableWidget->setColumnWidth(1,150);
    ui->tableWidget->setColumnWidth(2,300);
    ui->tableWidget->setColumnWidth(3,300);
    ui->tableWidget->setColumnWidth(4,100);
    ui->tableWidget->setColumnWidth(5,100);
    ui->tableWidget->setColumnWidth(6,1000);


    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->verticalHeader()->setVisible(false);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->treeWidget->setHeaderHidden(true);
}

MainWindow::~MainWindow()
{
    // 释放分配的内存
    int dataSzie = pData.size();
    for(int i = 0; i < dataSzie; i++){
        free((char*)(this->pData[i].pkt_content));
        this->pData[i].pkt_content = nullptr;
    }
    QVector<Datapackage>().swap(pData);
    delete readOnlyDelegate;
    delete ui;
}

void MainWindow::showNetworkCard()
{
    // 调用 pcap 库中的函数，查找计算机上的所有网络接口，并将它们保存在all_device变量中
    int n = pcap_findalldevs(&all_device, errbuf);
    ui->comboBox->clear();
    if(n == -1){ // 如果查找失败
        statusBar()->showMessage("There is something wrong" + QString(errbuf));
        ui->comboBox->addItem("error: " + QString(errbuf)); // 向UI的下拉框添加错误信息
    }else{ // 如果查找成功
        ui->comboBox->clear(); // 清空UI下拉框
        ui->comboBox->addItem("pls choose card!"); // 向 UI 界面的下拉框中添加一个提示项，告诉用户需要选择一个网络接口。
        for(device = all_device; device != nullptr; device = device->next){ // 遍历 all_device 中保存的所有网络接口。
            QString device_name = device->name; // 获取当前网络接口的名称。
            device_name.replace("\\Device\\", ""); // 去除名称中的多余字符。
            QString des = device->description; // 获取当前网络接口的描述信息。
            QString item = device_name + des; // 将名称和描述信息拼接为一个字符串。
            ui->comboBox->addItem(item); // 将拼接后的字符串添加到 UI 界面中的下拉框中。

        }
    }
}

int MainWindow::capture()
{
    // 检查是否存在可用的网络设备
    if(device){
        // 打开指定的网络设备以捕获数据包
        pointer = pcap_open_live(device->name, 65536,1,1000, errbuf);
    }else{
        // 如果没有可用的网络设备，则返回错误代码
        return -1;
    }
    // 检查是否成功打开了网络设备以捕获数据包
    if(!pointer){
        // 释放所有网络设备句柄
        pcap_freealldevs(all_device);
        device = nullptr;
        // 返回错误代码
        return -1;
    }else{
        // 检查网络设备的数据链路类型是否为Ethernet
        if(pcap_datalink(pointer) != DLT_EN10MB){
            // 如果不是Ethernet类型，关闭网络设备句柄并释放所有设备句柄
            pcap_close(pointer);
            pcap_freealldevs(all_device);
            all_device = nullptr;
            pointer = nullptr;
            device = nullptr;

            // 返回错误代码
            return -1;
        }
        // 在状态栏显示设备名称
        statusBar()->showMessage(device->name);
    }
    // 返回0表示捕获数据包成功
    return 0;
}

void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    int i = 0; // 声明一个变量i并初始化为0
    if(index != 0) // 如果下拉框的当前选择项不为第一项（index不等于0）
    {
        // 从all_device链表中遍历到index-1个设备节点
        for(device = all_device; i < index - 1; device = device->next,i++);
    }
    return; // 返回函数

}

void MainWindow::HandleMessage(Datapackage data)
{
    // 在控制台输出数据包的时间戳和信息
    //qDebug() << data.getTimeStamp() << "" << data.getInfo();

    ui->tableWidget->insertRow(countNumber);  // 在表格中插入一行
    this->pData.push_back(data);  // 将数据加入到数据结构中
    QString type = data.getPackageType();  // 获取数据包类型
    QColor color;  // 创建颜色对象
    if(type == "TCP"){  // 如果数据包类型为TCP
        color = QColor(216,191,216);  // 设置颜色为淡紫色
    }
    else if(type == "UDP"){  // 如果数据包类型为UDP
        color = QColor(144,238,144);  // 设置颜色为淡绿色
    }
    else if(type == "ARP"){  // 如果数据包类型为ARP
        color = QColor(238,238,0);  // 设置颜色为黄色
    }
    else if(type == "DNS"){  // 如果数据包类型为DNS
        color = QColor(255,255,224);  // 设置颜色为淡黄色
    }
    else if(type == "TLS" || type =="SSL"){  // 如果数据包类型为TLS或SSL
        color = QColor(210,149,210);  // 设置颜色为淡紫色
    }
    else{  // 如果数据包类型为其他类型
        color = QColor(255,210,185);  // 设置颜色为淡橙色
    }
    ui->tableWidget->setItem(countNumber, 0, new QTableWidgetItem(QString::number(countNumber)));  // 在表格中设置行号
    ui->tableWidget->setItem(countNumber, 1, new QTableWidgetItem(data.getTimeStamp()));  // 在表格中设置时间戳
    ui->tableWidget->setItem(countNumber, 2, new QTableWidgetItem(data.getSource()));  // 在表格中设置源地址
    ui->tableWidget->setItem(countNumber, 3, new QTableWidgetItem(data.getDestination()));  // 在表格中设置目的地址
    ui->tableWidget->setItem(countNumber, 4, new QTableWidgetItem(type));  // 在表格中设置数据包类型
    ui->tableWidget->setItem(countNumber, 5, new QTableWidgetItem(data.getDatalength()));  // 在表格中设置数据长度
    ui->tableWidget->setItem(countNumber, 6, new QTableWidgetItem(data.getInfo()));  // 在表格中设置数据信息
    for(int i = 0; i < 7; i++){  // 遍历表格中的每个单元格
        ui->tableWidget->item(countNumber, i)->setBackgroundColor(color);  // 将单元格的背景颜色设置为上面定义的颜色
    }
    countNumber++;  // 行号自增加1

}

void MainWindow::on_tableWidget_cellClicked(int row, int column)
{
    // 如果点击的行数等于之前选择的行数或小于0，直接返回
    if(row == numberRow || row < 0){
        return;
    }else{
        // 清空树形结构
        ui->treeWidget->clear();
        // 更新当前选择的行数
        numberRow = row;
        // 如果当前选择的行数小于0或大于数据包数量，直接返回
        if(numberRow < 0 || numberRow > countNumber){
            return;
        }
        // 获取目的MAC地址、源MAC地址和MAC类型
        QString desMac = pData[numberRow].getDestination();
        QString srcMac = pData[numberRow].getSrcMacAddr();
        QString type = pData[numberRow].getMacType();
        // 构建树形结构的第一层节点
        QString tree = "Ethernet,Src:" + srcMac + "Dst:" + desMac;
        QTreeWidgetItem *item = new QTreeWidgetItem(QStringList()<<tree);
        ui->treeWidget->addTopLevelItem(item);
        // 添加树形结构的子节点：目的MAC地址、源MAC地址和MAC类型
        item->addChild(new QTreeWidgetItem(QStringList() << "Destination:" + desMac));
        item->addChild(new QTreeWidgetItem(QStringList() << "Source:" + srcMac));
        item->addChild(new QTreeWidgetItem(QStringList() << "Type:" + type));
        // 获取数据包类型
        QString packageType = pData[numberRow].getPackageType();
        // 如果是ARP包
        if(packageType == "ARP"){
            // 获取ARP操作码
            QString ArpType = pData[numberRow].getArpOperationCode();
            // 构建树形结构的第二层节点
            QTreeWidgetItem*item2 = new QTreeWidgetItem(QStringList()<<"Address Resolution Protocol " + ArpType);
            ui->treeWidget->addTopLevelItem(item2);
            // 获取ARP包的各个字段
            QString HardwareType = pData[numberRow].getArpHardwareType();
            QString protocolType = pData[numberRow].getArpProtocolType();
            QString HardwareSize = pData[numberRow].getArpHardwareLength();
            QString protocolSize = pData[numberRow].getArpProtocolLength();
            QString srcMacAddr = pData[numberRow].getArpSourceEtherAddr();
            QString desMacAddr = pData[numberRow].getArpDestinationEtherAddr();
            QString srcIpAddr = pData[numberRow].getArpSourceIpAddr();
            QString desIpAddr = pData[numberRow].getArpDestinationIpAddr();
            // 添加树形结构的子节点：ARP包的各个字段
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Hardware type:" + HardwareType));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Protocol type:" + protocolType));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Hardware size:" + HardwareSize));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Protocol size:" + protocolSize));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Opcode:" + ArpType));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Sender MAC address:" + srcMacAddr));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Sender IP address:" + srcIpAddr));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Target MAC address:" + desMacAddr));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Target IP address:" + desIpAddr));
            return;
        }else { //IP包分析
            // 获取源地址和目的地址
            QString srcIp = pData[numberRow].getSrcIpAddr();
            QString desIp = pData[numberRow].getDesIpAddr();
            // 添加一个顶层节点，表示IP协议分析结果
            QTreeWidgetItem*item3 = new QTreeWidgetItem(QStringList()<<"Internet Protocol Version 4, Src:" + srcIp + ", Dst:" + desIp);
            ui->treeWidget->addTopLevelItem(item3);

            // 获取IP协议的各个字段
            QString version = pData[numberRow].getIpVersion();
            QString headerLength = pData[numberRow].getIpHeaderLength();
            QString Tos = pData[numberRow].getIpTos();
            QString totalLength = pData[numberRow].getIpTotalLength();
            QString id = "0x" + pData[numberRow].getIpIdentification();
            QString flags = pData[numberRow].getIpFlag();
            // 如果flags只有1位，则在前面补0
            if(flags.size()<2)
                flags = "0" + flags;
            flags = "0x" + flags;
            QString FragmentOffset = pData[numberRow].getIpFragmentOffset();
            QString ttl = pData[numberRow].getIpTTL();
            QString protocol = pData[numberRow].getIpProtocol();
            QString checksum = "0x" + pData[numberRow].getIpCheckSum();
            int dataLengthofIp = totalLength.toUtf8().toInt() - 20;

            // 添加IP协议分析结果的各个子节点
            item3->addChild(new QTreeWidgetItem(QStringList()<<"0100 .... = Version:" + version));
            item3->addChild(new QTreeWidgetItem(QStringList()<<".... 0101 = Header Length:" + headerLength));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"TOS:" + Tos));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Total Length:" + totalLength));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Identification:" + id));

            // 获取IP协议中的标志位，并将其添加到子节点中
            QString reservedBit = pData[numberRow].getIpReservedBit();
            QString DF = pData[numberRow].getIpDF();
            QString MF = pData[numberRow].getIpMF();
            QString FLAG = ",";

            if(reservedBit == "1"){ // 判断Reserved bit是否为1
                FLAG += "Reserved bit";
            }
            else if(DF == "1"){ // 判断Don't fragment是否为1
                FLAG += "Don't fragment";
            }
            else if(MF == "1"){ // 判断More fragment是否为1
                FLAG += "More fragment";
            }
            if(FLAG.size() == 1) // 如果没有标志位，FLAG为空
                FLAG = "";
            QTreeWidgetItem*bitTree = new QTreeWidgetItem(QStringList()<<"Flags:" + flags + FLAG); // 添加标志位子节点
            item3->addChild(bitTree);
            QString temp = reservedBit == "1"?"Set":"Not set"; // 判断Reserved bit是否为1
            bitTree->addChild(new QTreeWidgetItem(QStringList()<<reservedBit + "... .... = Reserved bit:" + temp));
            temp = DF == "1"?"Set":"Not set"; // 判断Don't fragment是否为1
            bitTree->addChild(new QTreeWidgetItem(QStringList()<<"." + DF + ".. .... = Don't fragment:" + temp));
            temp = MF == "1"?"Set":"Not set"; // 判断More fragment是否为1
            bitTree->addChild(new QTreeWidgetItem(QStringList()<<".." + MF + ". .... = More fragment:" + temp));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Fragment Offset:" + FragmentOffset)); // 添加Fragment Offset节点
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Time to Live:" + ttl)); // 添加Time to Live节点
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Protocol:" + protocol)); // 添加Protocol节点
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Header checksum:" + checksum)); // 添加Header checksum节点
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Source Address:" + srcIp)); // 添加Source Address节点
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Destination Address:" + desIp)); // 添加Destination Address节点
            if(packageType == "TCP" || packageType == "TLS" || packageType == "SSL"){ // 如果是TCP、TLS或SSL协议
                QString desPort = pData[numberRow].getTcpDestinationPort(); // 获取目的端口号
                QString srcPort = pData[numberRow].getTcpSourcePort(); // 获取源端口号
                QString ack = pData[numberRow].getTcpAcknowledgment(); // 获取确认号
                QString seq = pData[numberRow].getTcpSequence(); // 获取序列号
                QString headerLength = pData[numberRow].getTcpHeaderLength(); // 获取TCP头长度
                int rawLength = pData[numberRow].getTcpRawHeaderLength().toUtf8().toInt(); // 获取TCP头中的原始长度
                dataLengthofIp -= (rawLength * 4); // 计算TCP数据长度
                QString dataLength = QString::number(dataLengthofIp); // 将TCP数据长度转换为字符串
                QString flag = pData[numberRow].getTcpFlags(); // 获取TCP标志位
                while(flag.size()<2) // 当 flag 字符串长度小于 2 时循环
                    flag = "0" + flag; // 在 flag 前添加字符 '0'
                flag = "0x" + flag; // 在 flag 前添加字符串 "0x"
                QTreeWidgetItem* item4 = new QTreeWidgetItem(QStringList() << "Transmission Control Protocol, Src Port:" + srcPort + ", Dst Port:" + desPort + ", Seq:" + seq + ", Ack:" + ack + ", Len:" + dataLength); // 创建一个 QTreeWidgetItem 对象，设置其文本内容为 TCP 协议的信息
                ui->treeWidget->addTopLevelItem(item4); // 将 item4 添加为树形控件的顶层项目
                item4->addChild(new QTreeWidgetItem(QStringList() << "Source Port:" + srcPort)); // 将 "Source Port" 添加为 item4 的子项目
                item4->addChild(new QTreeWidgetItem(QStringList() << "Destination Port:" + desPort)); // 将 "Destination Port" 添加为 item4 的子项目
                item4->addChild(new QTreeWidgetItem(QStringList() << "Sequence Number (raw) :" + seq)); // 将 "Sequence Number (raw)" 添加为 item4 的子项目
                item4->addChild(new QTreeWidgetItem(QStringList() << "Ackowledgment Number (raw) :" + ack)); // 将 "Ackowledgment Number (raw)" 添加为 item4 的子项目
                QString sLength = QString::number(rawLength,2); // 将 rawLength 转换为二进制字符串，并赋值给 sLength
                while(sLength.size()<4) // 当 sLength 字符串长度小于 4 时循环
                    sLength = "0" + sLength; // 在 sLength 前添加字符 '0'
                item4->addChild(new QTreeWidgetItem(QStringList() << sLength + " .... = Header Length:" + headerLength)); // 将带有 Header Length 信息的字符串添加为 item4 的子项目
                QString PSH = pData[numberRow].getTcpPSH(); // 获取 TCP PSH 标志位的值
                QString URG = pData[numberRow].getTcpURG(); // 获取 TCP URG 标志位的值
                QString ACK = pData[numberRow].getTcpACK(); // 获取 TCP ACK 标志位的值
                QString RST = pData[numberRow].getTcpRST(); // 获取 TCP RST 标志位的值
                QString SYN = pData[numberRow].getTcpSYN(); // 获取 TCP SYN 标志位的值
                QString FIN = pData[numberRow].getTcpFIN(); // 获取 TCP FIN 标志位的值
                QString FLAG = ""; // 定义一个空字符串 FLAG
                if(PSH == "1")
                    FLAG += "PSH,";
                if(URG == "1")
                    FLAG += "UGR,";
                if(ACK == "1")
                    FLAG += "ACK,";
                if(RST == "1")
                    FLAG += "RST,";
                if(SYN == "1")
                    FLAG += "SYN,";
                if(FIN == "1")
                    FLAG += "FIN,";
                // 如果FLAG不为空，则去掉最后一个逗号
                FLAG = FLAG.left(FLAG.length()-1);
                // 如果SYN为1，则添加Sequence Number和Acknowledgment Number的QTreeWidgetItem
                if(SYN == "1"){
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number: 0 (relative sequence number)"));
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Acknowledgment Number: 0 (relative ack number)"));
                }
                // 如果SYN和ACK都为1，则添加Sequence Number和Acknowledgment Number的QTreeWidgetItem
                if(SYN == "1" && ACK == "1"){
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number: 0 (relative sequence number)"));
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Acknowledgment Number: 1 (relative ack number)"));
                }
                // 创建Flags的QTreeWidgetItem，并添加到item4中
                QTreeWidgetItem*flagTree = new QTreeWidgetItem(QStringList()<<"Flags:" + flag + " (" + FLAG + ")");
                item4->addChild(flagTree);
                // 添加URG、ACK、PSH、RST、SYN、FIN的QTreeWidgetItem，并添加到flagTree中
                QString temp = URG == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .." + URG + ". .... = Urgent(URG):" + temp));
                temp = ACK == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... ..." + ACK + " .... = Acknowledgment(ACK):" + temp));
                temp = PSH == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... " + PSH + "... = Push(PSH):" + temp));
                temp = RST == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... ." + RST + ".. = Reset(RST):" + temp));
                temp = SYN == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... .." + SYN + ". = Syn(SYN):" + temp));
                temp = FIN == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... ..." + FIN + " = Fin(FIN):" + temp));
                // 获取TCP窗口大小并转为字符串
                QString window = pData[numberRow].getTcpWindowSize();
                // 获取TCP校验和并添加"0x"前缀转为字符串
                QString checksum = "0x" + pData[numberRow].getTcpCheckSum();
                // 获取TCP紧急指针并转为字符串
                QString urgent = pData[numberRow].getTcpUrgentPointer();
                // 创建并添加TCP窗口大小的QTreeWidgetItem
                item4->addChild(new QTreeWidgetItem(QStringList()<<"window:" + window));
                // 创建并添加TCP校验和的QTreeWidgetItem
                item4->addChild(new QTreeWidgetItem(QStringList()<<"checksum:" + checksum));
                // 创建并添加TCP紧急指针的QTreeWidgetItem
                item4->addChild(new QTreeWidgetItem(QStringList()<<"Urgent Pointer:" + urgent));
                // 如果TCP头部选项长度大于20个字节
                if((rawLength * 4) > 20){
                    // 创建并添加TCP头部选项的QTreeWidgetItem，显示选项长度
                    QTreeWidgetItem * optionTree = new QTreeWidgetItem(QStringList()<<"Options: (" + QString::number(rawLength * 4 - 20) + ") bytes");
                    item4->addChild(optionTree);
                    // 对每一个选项进行处理
                    for(int j = 0;j < (rawLength * 4 - 20);){
                        // 获取当前选项的种类
                        int kind = pData[numberRow].getTcpOperationRawKind(j);
                        // 根据种类进行处理
                        switch (kind) {
                        case 0:{
                            // 如果是结束符选项，创建并添加对应的QTreeWidgetItem
                            QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - End of List (EOL)");
                            optionTree->addChild(subTree);
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind:End of List (0)"));
                            optionTree->addChild(subTree);
                            j++;
                            break;
                        }case 1:{
                            // 如果是无操作选项，创建并添加对应的QTreeWidgetItem
                            QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - No-Operation (NOP)");
                            optionTree->addChild(subTree);
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind: No-Operation (1)"));
                            optionTree->addChild(subTree);
                            j++;
                            break;
                        }
                        case 2:{
                            // 如果是最大报文段长度选项，获取选项内容并创建对应的QTreeWidgetItem
                            u_short mss;
                            if(pData[numberRow].getTcpOperationMSS(j,mss)){
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - Maximun Segment Size: " + QString::number(mss) + " bytes");
                                optionTree->addChild(subTree);
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind: Maximun Segment Size (2)"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 4"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"MSS Value: " + QString::number(mss)));
                                j += 4;
                            }
                            break;
                        }
                    case 3:{
                            // 定义偏移量的变量shift
                            u_char shift;
                            // 如果TCP选项中有窗口缩放选项
                            if(pData[numberRow].getTcpOperationWSOPT(j,shift)){
                                // 计算窗口缩放因子
                                int factor = 1 << shift;
                                // 创建一个TCP Option - Window scale的子节点，显示窗口缩放因子和选项信息
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - Window scale: " + QString::number(shift) + " (multiply by " + QString::number(factor) + ")");
                                // 添加子节点到optionTree节点下
                                optionTree->addChild(subTree);
                                // 添加子节点的子节点，表示选项的kind
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind: Window scale (3)"));
                                // 添加子节点的子节点，表示选项长度为3
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 3"));
                                // 添加子节点的子节点，表示窗口缩放的偏移量
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Shift Count: " + QString::number(shift)));
                                // 添加子节点的子节点，显示窗口缩放因子
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"[Multiplier: " + QString::number(factor) + "]"));
                                // 将选项偏移量加上3，跳过该选项的内容
                                j += 3;
                            }
                        break;
                    }
                    case 4:{
                            // 如果TCP选项中有SACK Permitted选项
                            if(pData[numberRow].getTcpOperationSACKP(j)){
                                // 创建一个TCP Option - SACK Permitted的子节点
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - SACK Permitted");
                                // 添加子节点到optionTree节点下
                                optionTree->addChild(subTree);
                                // 添加子节点的子节点，表示选项的kind
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Kind: SCAK Permitted (4)"));
                                // 添加子节点的子节点，表示选项长度为2
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 2"));
                                // 将选项偏移量加上2，跳过该选项的内容
                                j += 2;
                            }
                        break;
                    }
                    case 5:{
                        u_char length = 0;
                        QVector<u_int>edge;
                        if(pData[numberRow].getTcpOperationSACK(j,length,edge)){
                            QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - SACK");
                            optionTree->addChild(subTree);
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Kind: SCAK (5)"));
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(length)));
                            int num = edge.size();
                            for(int k = 0;k < num;k += 2){
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"left edge = " + QString::number(edge[k])));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"right edge = " + QString::number(edge[k + 1])));
                            }
                            j += length;
                        }
                        break;
                    }
                    case 8:{
                        u_int value = 0;
                        u_int reply = 0;
                        if(pData[numberRow].getTcpOperationTSPOT(j,value,reply)){
                            QString val = QString::number(value);
                            QString rep = QString::number(reply);
                            QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - TimeStamps: TSval " +val + ", TSecr " + rep);
                            optionTree->addChild(subTree);
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Kind: Time Stamp Option (8)"));
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 10"));
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Timestamp value: " + val));
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Timestamp echo reply: " + rep));
                            j += 10;
                        }
                        break;
                    }
                    case 19:{
                        j += 18;
                        break;
                    }
                    case 28:{
                        j += 4;
                        break;
                    }
                    default:{
                        j++;
                        break;
                    }
                    }
                }
            }
            if(dataLengthofIp > 0){
                item4->addChild(new QTreeWidgetItem(QStringList()<<"TCP Payload (" + QString::number(dataLengthofIp) + ")"));
                if(packageType == "TLS"
                        ){
                    QTreeWidgetItem* tlsTree = new QTreeWidgetItem(QStringList()<<"Transport Layer Security");
                    ui->treeWidget->addTopLevelItem(tlsTree);
                    u_char contentType = 0;
                    u_short version = 0;
                    u_short length = 0;
                    pData[numberRow].getTlsBasicInfo((rawLength * 4),contentType,version,length);
                    QString type = pData[numberRow].getTlsContentType(contentType);
                    QString vs = pData[numberRow].getTlsVersion(version);
                    switch (contentType) {
                    case 20:{
                        //……待办事项
                        break;
                    }
                     case 21:{
                         QTreeWidgetItem* tlsSubree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: Encrypted Alert");
                         tlsTree->addChild(tlsSubree);
                         tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                         tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                         tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));
                         tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Alert Message: Encrypted Alert"));
                         break;
                     }
                     case 22:{ //握手
                        u_char handshakeType = 0;
                        pData[numberRow].getTlsHandshakeType((rawLength * 4 + 5),handshakeType);
                        if(handshakeType == 1){ // client hello
                            int tlsLength = 0;
                            u_short rawVersion = 0;
                            QString random = "";
                            u_char sessionLength = 0;
                            QString sessionId = "";
                            u_short cipherLength = 0;
                            QVector<u_short>cipher;
                            u_char cmLength = 0;
                            QVector<u_char>compressionMethod;
                            u_short extensionLength = 0;
                           pData[numberRow].getTlsClientHelloInfo((rawLength * 4 + 5),handshakeType,tlsLength,rawVersion,random,sessionLength,sessionId,cipherLength,cipher,cmLength,compressionMethod,extensionLength);

                            QString type = pData[numberRow].getTlsHandshakeType(handshakeType);
                            QString tlsVersion = pData[numberRow].getTlsVersion(rawVersion);

                            QTreeWidgetItem* tlsSubTree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: " + type);
                            tlsTree->addChild(tlsSubTree);
                            tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                            tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                            tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));

                            QTreeWidgetItem* handshakeTree = new QTreeWidgetItem(QStringList()<<"Handshake Protocol: " + type);
                            tlsSubTree->addChild(handshakeTree);
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Handshake Type: " + type + "(" + QString::number(handshakeType) + ")"));
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(tlsLength)));

                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + tlsVersion + " (0x0" + QString::number(rawVersion) + ")"));
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Random: " + random));
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID Length: " + QString::number(sessionLength)));
                            if(sessionLength > 0){
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID: " + sessionId));
                            }
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Cipher Suites Length: " + QString::number(cipherLength)));
                            if(cipherLength > 0){
                                QTreeWidgetItem* cipherTree = new QTreeWidgetItem(QStringList()<<"Cipher Suites (" + QString::number(cipherLength/2) + " suites)");
                                handshakeTree->addChild(cipherTree);
                                for(int k = 0;k < cipherLength/2;k++){
                                    QString temp = pData[numberRow].getTlsHandshakeCipherSuites(cipher[k]);
                                    cipherTree->addChild(new QTreeWidgetItem(QStringList()<<"Cipher Suite: " + temp));
                                }
                            }
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Compression Method Length: " + QString::number(cmLength)));
                            if(cmLength > 0){
                                QTreeWidgetItem* cmTree = new QTreeWidgetItem(QStringList()<<"Compression Methods (" + QString::number(cmLength) + " method)");
                                handshakeTree->addChild(cmTree);
                                for(int k = 0;k < cmLength;k++){
                                QString temp = pData[numberRow].getTlsHandshakeCompression(compressionMethod[k]);
                                cmTree->addChild(new QTreeWidgetItem(QStringList()<<"Compression Methods: " + temp + " (" + QString::number(compressionMethod[k]) + ")"));
                            }
                        }
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Extensions Length: " + QString::number(extensionLength)));
                        if(extensionLength > 0){
                            int exOffset = (rawLength * 4) + (tlsLength - extensionLength + 5 + 4);
                            for(int k = 0;k < extensionLength;){
                                int code = pData[numberRow].getTlsExtensionType(exOffset);
                                u_short exType = 0;
                                u_short exLength = 0;
                                switch (code) {
                                case 0:{ //服务器的名称
                                    u_short listLength = 0;
                                    u_char nameType = 0;
                                    u_short nameLength = 0;
                                    QString name = "";
                                    pData[numberRow].getTlsExtensionServerName(exOffset,exType,exLength,listLength,nameType,nameLength,name);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    if(exLength > 0 && listLength > 0){
                                        QTreeWidgetItem*serverTree = new QTreeWidgetItem(QStringList()<<"Server Name Indication extension");
                                        extensionTree->addChild(serverTree);
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name list length: " + QString::number(listLength)));
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name Type: " + QString::number(nameType)));
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name length: " + QString::number(nameLength)));
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name: " + name));
                                    }
                                    break;
                                }
                                case 11:{// Ec点格式
                                    u_char ecLength = 0;
                                    QVector<u_char>EC;
                                    pData[numberRow].getTlsExtensionEcPointFormats(exOffset,exType,exLength,ecLength,EC);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"EC point formats Length: " + QString::number(ecLength)));
                                    QTreeWidgetItem* EXTree = new QTreeWidgetItem(QStringList()<<"Elliptic curves point formats (" + QString::number(ecLength) + ")");
                                    extensionTree->addChild(EXTree);
                                    for(int g = 0;g < ecLength;g++){
                                        QString temp = pData[numberRow].getTlsHandshakeExtensionECPointFormat(EC[g]);
                                        EXTree->addChild(new QTreeWidgetItem(QStringList()<<temp));
                                    }
                                    break;
                                }
                                case 10:{// supported_groups
                                    u_short groupListLength = 0;
                                    QVector<u_short>group;
                                    pData[numberRow].getTlsExtensionSupportGroups(exOffset,exType,exLength,groupListLength,group);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Groups List Length: " + QString::number(groupListLength)));
                                    QTreeWidgetItem* sptTree = new QTreeWidgetItem(QStringList()<<"Supported Groups (" + QString::number(groupListLength/2) + " groups)");
                                    extensionTree->addChild(sptTree);
                                    for(int g = 0;g < groupListLength/2;g++){
                                        QString temp = pData[numberRow].getTlsHandshakeExtensionSupportGroup(group[g]);
                                        sptTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Group: " + temp));
                                    }
                                    break;
                                }
                                case 35:{// session_ticket
                                    pData[numberRow].getTlsExtensionSessionTicket(exOffset,exType,exLength);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    break;
                                }
                                case 22:{// encrypt_then_mac
                                    pData[numberRow].getTlsExtensionEncryptThenMac(exOffset,exType,exLength);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    break;
                                }
                                case 23:{// extended_master_secret
                                    pData[numberRow].getTlsExtensionExtendMasterSecret(exOffset,exType,exLength);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    break;
                                }
                                case 13:{// signature_algorithms
                                    u_short algorithmLength = 0;
                                    QVector<u_short>algorithm;
                                    pData[numberRow].getTlsExtensionSignatureAlgorithms(exOffset,exType,exLength,algorithmLength,algorithm);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms Length: " + QString::number(algorithmLength)));
                                    QTreeWidgetItem* sigTree = new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms (" + QString::number(algorithmLength/2) + " algorithms)");
                                    extensionTree->addChild(sigTree);
                                    for(int g = 0;g < algorithmLength/2;g++){
                                        QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Signature Algorithm: 0x0" + QString::number(algorithm[g],16));
                                        sigTree->addChild(subTree);
                                        QString hash = pData[numberRow].getTlsHadshakeExtensionHash((algorithm[g] & 0xff00) >> 8);
                                        QString sig = pData[numberRow].getTlsHadshakeExtensionSignature((algorithm[g] & 0x00ff));
                                        subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Hash: " + hash + " (" + QString::number((algorithm[g] & 0xff00) >> 8) + ")"));
                                        subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Signature: " + sig + " (" + QString::number(algorithm[g] & 0x00ff) + ")"));
                                    }
                                    break;
                                }
                                case 43:{// supported_versions
                                    u_char supportLength = 0;
                                    QVector<u_short>supportVersion;
                                    pData[numberRow].getTlsExtensionSupportVersions(exOffset,exType,exLength,supportLength,supportVersion);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Versions length: " + QString::number(supportLength)));
                                    for(int g = 0;g < supportLength/2;g++){
                                        QString temp = pData[numberRow].getTlsVersion(supportVersion[g]);
                                        extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Version: " + temp));
                                    }
                                    break;
                                }
                                case 51:{// key_share
                                    u_short shareLength = 0;
                                    u_short group = 0;
                                    u_short exchangeLength = 0;
                                    QString exchange = "";
                                    pData[numberRow].getTlsExtensionKeyShare(exOffset,exType,exLength,shareLength,group,exchangeLength,exchange);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));

                                    QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Key Share extension");
                                    extensionTree->addChild(subTree);
                                    subTree->addChild(new QTreeWidgetItem(QStringList()<<"Client Key Share Length: " + QString::number(shareLength)));
                                    QTreeWidgetItem* entryTree = new QTreeWidgetItem(QStringList()<<"Key Share Entry: Group ");
                                    subTree->addChild(entryTree);
                                    entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Group: " + QString::number(group)));
                                    entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange Length: " + QString::number(exchangeLength)));
                                    entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange: " + exchange));
                                    break;
                                }
                                case 21:{// padding
                                    QString rdata = "";
                                    pData[numberRow].getTlsExtensionPadding(exOffset,exType,exLength,rdata);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (21)"));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Padding Data: " + rdata));
                                    break;
                                }
                                default:{
                                    QString rdata = "";
                                    pData[numberRow].getTlsExtensionOther(exOffset,exType,exLength,rdata);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (" + QString::number(exType) + ")"));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Data: " + rdata));

                                    break;
                                }
                                k += (exLength + 4);
                                exOffset += (exLength + 4);
                            }
                        }
                    }
                    else if(handshakeType == 2){// Server hello
                        int tlsLength = 0;
                        u_short rawVersion = 0;
                        QString random = "";
                        u_char sessionLength = 0;
                        QString sessionId = "";
                        u_short cipher = 0;
                        u_char compressionMethod = 0;
                        u_short extensionLength = 0;
                        pData[numberRow].getTlsServerHelloInfo((rawLength * 4 + 5),handshakeType,tlsLength,rawVersion,random,sessionLength,sessionId,cipher,compressionMethod,extensionLength);
                        QString type = pData[numberRow].getTlsHandshakeType(handshakeType);
                        QString tlsVersion = pData[numberRow].getTlsVersion(rawVersion);

                        QTreeWidgetItem* tlsSubTree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: " + type);
                        tlsTree->addChild(tlsSubTree);
                        tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                        tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                        tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));

                        QTreeWidgetItem* handshakeTree = new QTreeWidgetItem(QStringList()<<"Handshake Protocol: " + type);
                        tlsSubTree->addChild(handshakeTree);
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Handshake Type: " + type + "(" + QString::number(handshakeType) + ")"));
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(tlsLength)));

                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + tlsVersion + " (0x0" + QString::number(rawVersion,16) + ")"));
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Random: " + random));
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID Length: " + QString::number(sessionLength)));
                        if(sessionLength > 0){
                            handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID: " + sessionId));
                        }
                        QString temp = pData[numberRow].getTlsHandshakeCipherSuites(cipher);
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Cipher Suites: " +temp));
                        temp = pData[numberRow].getTlsHandshakeCompression(compressionMethod);
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Compression Methods: " + temp + " (" + QString::number(compressionMethod) + ")"));
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Extensions Length: " + QString::number(extensionLength)));
                        if(extensionLength > 0){
                            int exOffset = (rawLength * 4) + (tlsLength - extensionLength + 5 + 4);
                            for(int k = 0;k < extensionLength;){
                                int code = pData[numberRow].getTlsExtensionType(exOffset);
                                u_short exType = 0;
                                u_short exLength = 0;
                                switch (code) {
                                case 0:{ // server_name
                                    u_short listLength = 0;
                                    u_char nameType = 0;
                                    u_short nameLength = 0;
                                    QString name = "";
                                    pData[numberRow].getTlsExtensionServerName(exOffset,exType,exLength,listLength,nameType,nameLength,name);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    if(exLength > 0 && listLength > 0){
                                        QTreeWidgetItem*serverTree = new QTreeWidgetItem(QStringList()<<"Server Name Indication extension");
                                        extensionTree->addChild(serverTree);
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name list length: " + QString::number(listLength)));
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name Type: " + QString::number(nameType)));
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name length: " + QString::number(nameLength)));
                                        serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name: " + name));
                                    }
                                    break;
                                }
                                case 11:{// ec_point_format
                                    u_char ecLength = 0;
                                    QVector<u_char>EC;
                                    pData[numberRow].getTlsExtensionEcPointFormats(exOffset,exType,exLength,ecLength,EC);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"EC point formats Length: " + QString::number(ecLength)));
                                    QTreeWidgetItem* EXTree = new QTreeWidgetItem(QStringList()<<"Elliptic curves point formats (" + QString::number(ecLength) + ")");
                                    extensionTree->addChild(EXTree);
                                    for(int g = 0;g < ecLength;g++){
                                        QString temp = pData[numberRow].getTlsHandshakeExtensionECPointFormat(EC[g]);
                                        EXTree->addChild(new QTreeWidgetItem(QStringList()<<temp));
                                    }
                                    break;
                                }
                                case 10:{// supported_groups
                                    u_short groupListLength = 0;
                                    QVector<u_short>group;
                                    pData[numberRow].getTlsExtensionSupportGroups(exOffset,exType,exLength,groupListLength,group);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Groups List Length: " + QString::number(groupListLength)));
                                    QTreeWidgetItem* sptTree = new QTreeWidgetItem(QStringList()<<"Supported Groups (" + QString::number(groupListLength/2) + " groups)");
                                    extensionTree->addChild(sptTree);
                                    for(int g = 0;g < groupListLength/2;g++){
                                        QString temp = pData[numberRow].getTlsHandshakeExtensionSupportGroup(group[g]);
                                        sptTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Group: " + temp));
                                    }
                                    break;
                                }
                                case 35:{// session_ticket
                                    pData[numberRow].getTlsExtensionSessionTicket(exOffset,exType,exLength);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    break;
                                }
                                case 22:{// encrypt_then_mac
                                    pData[numberRow].getTlsExtensionEncryptThenMac(exOffset,exType,exLength);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    break;
                                }
                                case 23:{// extended_master_secret
                                    pData[numberRow].getTlsExtensionExtendMasterSecret(exOffset,exType,exLength);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    break;
                                }
                                case 13:{// signature_algorithms
                                    u_short algorithmLength = 0;
                                    QVector<u_short>algorithm;
                                    pData[numberRow].getTlsExtensionSignatureAlgorithms(exOffset,exType,exLength,algorithmLength,algorithm);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms Length: " + QString::number(algorithmLength)));
                                    QTreeWidgetItem* sigTree = new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms (" + QString::number(algorithmLength/2) + " algorithms)");
                                    extensionTree->addChild(sigTree);
                                    for(int g = 0;g < algorithmLength/2;g++){
                                        QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Signature Algorithm: 0x0" + QString::number(algorithm[g],16));
                                        sigTree->addChild(subTree);
                                        QString hash = pData[numberRow].getTlsHadshakeExtensionHash((algorithm[g] & 0xff00) >> 8);
                                        QString sig = pData[numberRow].getTlsHadshakeExtensionSignature((algorithm[g] & 0x00ff));
                                        subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Hash: " + hash + " (" + QString::number((algorithm[g] & 0xff00) >> 8) + ")"));
                                        subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Signature: " + sig + " (" + QString::number(algorithm[g] & 0x00ff) + ")"));
                                    }
                                    break;
                                }
                                case 43:{// supported_versions
                                    u_char supportLength = 0;
                                    QVector<u_short>supportVersion;
                                    pData[numberRow].getTlsExtensionSupportVersions(exOffset,exType,exLength,supportLength,supportVersion);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Versions length: " + QString::number(supportLength)));
                                    for(int g = 0;g < supportLength/2;g++){
                                        QString temp = pData[numberRow].getTlsVersion(supportVersion[g]);
                                        extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Version: " + temp));
                                    }
                                    break;
                                }
                                case 51:{// key_share
                                    u_short shareLength = 0;
                                    u_short group = 0;
                                    u_short exchangeLength = 0;
                                    QString exchange = "";
                                    pData[numberRow].getTlsExtensionKeyShare(exOffset,exType,exLength,shareLength,group,exchangeLength,exchange);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));

                                    QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Key Share extension");
                                    extensionTree->addChild(subTree);
                                    subTree->addChild(new QTreeWidgetItem(QStringList()<<"Client Key Share Length: " + QString::number(shareLength)));
                                    QTreeWidgetItem* entryTree = new QTreeWidgetItem(QStringList()<<"Key Share Entry: Group ");
                                    subTree->addChild(entryTree);
                                    entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Group: " + QString::number(group)));
                                    entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange Length: " + QString::number(exchangeLength)));
                                    entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange: " + exchange));
                                    break;
                                }
                                case 21:{// padding
                                    QString rdata = "";
                                    pData[numberRow].getTlsExtensionPadding(exOffset,exType,exLength,rdata);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (21)"));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Padding Data: " + rdata));
                                    break;
                                }
                                default:{
                                    QString rdata = "";
                                    pData[numberRow].getTlsExtensionOther(exOffset,exType,exLength,rdata);
                                    QString subType = pData[numberRow].getTlsHandshakeExtension(exType);
                                    QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                    handshakeTree->addChild(extensionTree);
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (" + QString::number(exType) + ")"));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                    extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Data: " + rdata));

                                    break;
                                }
                                }
                                k += (exLength + 4);
                                exOffset += (exLength + 4);
                            }
                        }

                    }
                    else if(handshakeType == 12){// Server Key Exchange
                        int tlsLength = 0;
                        u_char curveType = 0;
                        u_short curveName = 0;
                        u_char pubLength = 0;
                        QString pubKey = "";
                        u_short sigAlgorithm = 0;
                        u_short sigLength = 0;
                        QString sig = "";
                        pData[numberRow].getTlsServerKeyExchange((rawLength * 4 + 5),handshakeType,tlsLength,curveType,curveName,pubLength,pubKey,sigAlgorithm,sigLength,sig);
                        QString type = pData[numberRow].getTlsHandshakeType(handshakeType);

                        QTreeWidgetItem* tlsSubTree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: " + type);
                        tlsTree->addChild(tlsSubTree);
                        tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                        tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                        tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));

                        QTreeWidgetItem* handshakeTree = new QTreeWidgetItem(QStringList()<<"Handshake Protocol: " + type);
                        tlsSubTree->addChild(handshakeTree);
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Handshake Type: " + type + "(" + QString::number(handshakeType) + ")"));
                        handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(tlsLength)));

                    }
                    // ... TODO
                    break;
                }
              }
                case 23:{
                    QTreeWidgetItem* tlsSubree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: http-over-tls");
                    tlsTree->addChild(tlsSubree);
                    tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                    tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                    tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));
                    tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Encrypted Application Data: ..."));
                    break;
                }
                default:break;
                }
                }else if(packageType == "SSL"){
                    ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(QStringList()<<"Transport Layer Security"));
                }
            }
            }else if(packageType == "UDP" || packageType == "DNS"){
             QString srcPort = pData[numberRow].getUdpSourcePort();
             QString desPort = pData[numberRow].getUdpDestinationPort();
             QString Length = pData[numberRow].getUdpDataLength();
             QString checksum = "0x" + pData[numberRow].getUdpCheckSum();
             QTreeWidgetItem*item5 = new QTreeWidgetItem(QStringList()<<"User Datagram Protocol, Src Port:" + srcPort + ", Dst Port:" + desPort);
             ui->treeWidget->addTopLevelItem(item5);
             item5->addChild(new QTreeWidgetItem(QStringList()<<"Source Port:" + srcPort));
             item5->addChild(new QTreeWidgetItem(QStringList()<<"Destination Port:" + desPort));
             item5->addChild(new QTreeWidgetItem(QStringList()<<"length:" + Length));
             item5->addChild(new QTreeWidgetItem(QStringList()<<"Checksum:" + checksum));
             int udpLength = Length.toUtf8().toInt();
             if(udpLength > 0){
                 item5->addChild(new QTreeWidgetItem(QStringList()<<"UDP PayLoad (" + QString::number(udpLength - 8) + " bytes)"));
             }
             if(packageType == "DNS"){
                QString transaction = "0x" + pData[numberRow].getDnsTransactionId();
                QString QR = pData[numberRow].getDnsFlagsQR();
                QString temp = "";
                if(QR == "0") temp = "query";
                if(QR == "1") temp = "response";
                QString flags = "0x" + pData[numberRow].getDnsFlags();
                QTreeWidgetItem*dnsTree = new QTreeWidgetItem(QStringList()<<"Domain Name System (" + temp + ")");
                ui->treeWidget->addTopLevelItem(dnsTree);
                dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Transaction ID:" + transaction));
                QTreeWidgetItem* flagTree = new QTreeWidgetItem(QStringList()<<"Flags:" + flags);
                dnsTree->addChild(flagTree);
                temp = QR == "1"?"Message is a response":"Message is a query";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<QR + "... .... .... .... = Response:" + temp));
                QString Opcode = pData[numberRow].getDnsFlagsOpcode();
                if(Opcode == "0") temp = "Standard query (0)";
                else if(Opcode == "1") temp = "Reverse query (1)";
                else if(Opcode == "2") temp = "Status request (2)";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".000 " + Opcode + "... .... .... = Opcode:" + temp));
                if(QR == "1"){
                    QString AA = pData[numberRow].getDnsFlagsAA();
                    temp = AA == "1"?"Server is an authority for domain":"Server is not an authority for domain";
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... ." + AA + ".. .... .... = Authoritative:" + temp));
                }
                QString TC = pData[numberRow].getDnsFlagsTC();
                temp = TC == "1"?"Message is truncated":"Message is not truncated";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .." + TC + ". .... .... = Truncated:" + temp));

                QString RD = pData[numberRow].getDnsFlagsRD();
                temp = RD == "1"?"Do query recursively":"Do query not recursively";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... ..." + RD + " .... .... = Recursion desired:" + temp));

                if(QR == "1"){
                    QString RA = pData[numberRow].getDnsFlagsRA();
                    temp = RA == "1"?"Server can do recursive queries":"Server can not do recursive queries";
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... " + RA + "... .... = Recursion available:" + temp));
                }
                QString Z = pData[numberRow].getDnsFlagsZ();
                 while(Z.size()<3)
                     Z = "0" + Z;
                 flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... ." + Z + " .... = Z:reserved(" + Z + ")"));
                 if(QR == "1"){
                     QString Rcode = pData[numberRow].getDnsFlagsRcode();
                     if(Rcode == "0")
                         temp = "No error (0)";
                     else if(Rcode == "1") temp = "Format error (1)";
                     else if(Rcode == "2") temp = "Server failure (2)";
                     else if(Rcode == "3") temp = "Name Error (3)";
                     else if(Rcode == "4") temp = "Not Implemented (4)";
                     else if(Rcode == "5") temp = "Refused (5)";
                     int code = Rcode.toUtf8().toInt();
                     QString bCode = QString::number(code,2);
                     while (bCode.size()<4)
                         bCode = "0" + bCode;
                     flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... .... " + bCode + " = Reply code:" + temp));
                 }

                 QString question = pData[numberRow].getDnsQuestionNumber();
                 dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Questions:" + question));
                 QString answer = pData[numberRow].getDnsAnswerNumber();
                 dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Answer RRs:" + answer));
                 QString authority = pData[numberRow].getDnsAuthorityNumber();
                 dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Authority RRs:" + authority));
                 QString additional = pData[numberRow].getDnsAdditionalNumber();
                 dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Additional RRs:" + additional));
                 int offset = 0;
                 if(question == "1"){
                     QString domainInfo;
                     int Type;
                     int Class;
                     pData[numberRow].getDnsQueriesDomain(domainInfo,Type,Class);
                     QTreeWidgetItem*queryDomainTree = new QTreeWidgetItem(QStringList()<<"Queries");
                     dnsTree->addChild(queryDomainTree);
                     offset += (4 + domainInfo.size() + 2);
                     QString type = pData[numberRow].getDnsDomainType(Type);
                     QTreeWidgetItem*querySubTree = new QTreeWidgetItem(QStringList()<<domainInfo + " type " + type + ", class IN");
                     queryDomainTree->addChild(querySubTree);
                     querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"Name:" + domainInfo));
                     querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"[Name Length:" + QString::number(domainInfo.size()) + "]"));
                     querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"Type:" + type + "(" + QString::number(Type) + ")"));
                     querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"Class: IN (0x000" + QString::number(Class) + ")"));
                 }
                 int answerNumber = answer.toUtf8().toInt();
                 if(answerNumber > 0){
                     QTreeWidgetItem*answerTree = new QTreeWidgetItem(QStringList()<<"Answers");
                     dnsTree->addChild(answerTree);
                     for(int i = 0;i< answerNumber;i++){
                         QString name1;
                         QString name2;
                         u_short type;
                         u_short Class;
                         u_int ttl;
                         u_short length;

                         int tempOffset = pData[numberRow].getDnsAnswersDomain(offset,name1,type,Class,ttl,length,name2);
                         QString sType = pData[numberRow].getDnsDomainType(type);
                         QString temp = "";
                         if(type == 1) temp = "addr";
                         else if(type == 5) temp = "cname";
                         QTreeWidgetItem*answerSubTree = new QTreeWidgetItem(QStringList()<<name1 + ": type " + sType + ",class IN, " + temp + ":" + name2);
                         answerTree->addChild(answerSubTree);
                         answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Name:" + name1));
                         answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Type:" + sType + "(" + QString::number(type) + ")"));
                         answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Class: IN (0x000" + QString::number(Class) + ")"));
                         answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Time to live:" + QString::number(ttl) + "(" + QString::number(ttl) + " second)"));
                         answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Data length:" + QString::number(length)));
                         answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<sType + ":" + name2));

                         offset += tempOffset;
                     }
                               }
                           }
                       }else if(packageType == "ICMP"){
                           dataLengthofIp -= 8;
                           QTreeWidgetItem*item6 = new QTreeWidgetItem(QStringList()<<"Internet Message Protocol");
                           ui->treeWidget->addTopLevelItem(item6);
                           QString type = pData[numberRow].getIcmpType();
                           QString code = pData[numberRow].getIcmpCode();
                           QString info = ui->tableWidget->item(row,6)->text();
                           QString checksum = "0x" + pData[numberRow].getIcmpCheckSum();
                           QString id = pData[numberRow].getIcmpIdentification();
                           QString seq = pData[numberRow].getIcmpSequeue();
                           item6->addChild(new QTreeWidgetItem(QStringList()<<"type:" + type + "(" + info + ")"));
                           item6->addChild(new QTreeWidgetItem(QStringList()<<"code:" + code));
                           item6->addChild(new QTreeWidgetItem(QStringList()<<"Checksum:" + checksum));
                           item6->addChild(new QTreeWidgetItem(QStringList()<<"type:" + type + "(" + info + ")"));
                           item6->addChild(new QTreeWidgetItem(QStringList()<<"Identifier:" + id));
                           item6->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number:" + seq));
                           if(dataLengthofIp > 0){
                               QTreeWidgetItem* dataItem = new QTreeWidgetItem(QStringList()<<"Data (" + QString::number(dataLengthofIp) + ") bytes");
                               item6->addChild(dataItem);
                               QString icmpData = pData[numberRow].getIcmpData(dataLengthofIp);
                               dataItem->addChild(new QTreeWidgetItem(QStringList()<<icmpData));
                           }
                       }
                   }
                   // the ethernet may have padding to ensure that the minimum length of the data packet is greater than 46
                   int macDataLength = pData[numberRow].getIpTotalLength().toUtf8().toInt();
                   int dataPackageLength = pData[numberRow].getDatalength().toUtf8().toInt();
                   int delta = dataPackageLength - macDataLength;
                   if(delta > 14){
                       int padding = delta - 14;
                       QString pad = "";
                       while (pad.size() < padding * 2) {
                           pad += "00";
                       }
                       item->addChild(new QTreeWidgetItem(QStringList()<<"Padding: " + pad));
                   }
               }
           }

// 过滤器
void MainWindow::on_lineEdit_returnPressed()
{
    // 获取输入框的文本内容，并将其转换成大写字母
    QString text = ui->lineEdit->text();
    text = text.toUpper();
    QString target = "#";   // 定义目标协议
    // 如果输入为空或者输入的是已知协议，则将输入框背景色设置为绿色，并将目标协议设为相应的值
    if(text == "" || text == "UDP" || text == "TCP" || text == "DNS" || text == "ARP"|| text == "ICMP"|| text == "SSL" || text == "TLS"){
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(154,255,154);}");
        target = text;
    }
    // 否则将输入框背景色设置为红色
    else{
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(250,128,114);}");
    }

    int count = 0;          // 统计匹配的数据包数量
    int number = ui->tableWidget->rowCount();  // 获取当前表格中的数据包数量
    // 如果程序不在运行状态，并且目标协议不为默认值
    if(!isStart && target != "#"){
        if(target!=""){     // 如果目标协议不为空
            for(int i = 0; i < number; i++){  // 遍历所有数据包
                // 如果数据包协议与目标协议不同，则将该行隐藏
                if(ui->tableWidget->item(i,4)->text() != target){
                    ui->tableWidget->setRowHidden(i,true);
                }
                // 否则显示该行，并统计匹配的数据包数量
                else{
                    ui->tableWidget->setRowHidden(i,false);
                    count++;
                }
            }
        }else{              // 如果目标协议为空
            for(int i = 0; i < number; i++){  // 遍历所有数据包
                ui->tableWidget->setRowHidden(i,false);    // 显示所有行
                count++;        // 统计所有数据包数量
            }
        }
    }

    double res = 0;         // 计算匹配的数据包占全部数据包的比例
    if(number != 0)
        res = (count*100.0)/number;
    // 在状态栏中显示匹配数据包数量和比例信息
    statusBar()->showMessage("Have show (" + QString::number(count) + ") " +QString::number(res,10,2) + "%");
}


void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    QString text = arg1;        // 获取输入框的文本内容
    text = text.toLower();      // 将文本内容转换为小写字母
    // 如果文本内容为空或者文本内容为已知协议，则将输入框的背景色设为绿色
    if(text == "" || text == "udp" || text == "tcp" || text == "dns" || text == "arp" || text == "icmp" || text == "tls" || text == "ssl"){
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(154,255,154);}");
    }
    // 否则将输入框的背景色设为红色
    else{
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(250,128,114);}");
    }
}

void MainWindow::on_Tablewidget_Currentcellchanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
    // 如果当前选中单元格与上一次选中单元格不同，并且上一次选中行数大于等于0，
    // 则调用on_tableWidget_cellClicked函数
    if((currentRow != previousRow) && previousRow >= 0){
        on_tableWidget_cellClicked(currentRow,currentColumn);
    }
    // 否则直接返回
    else{
        return;
    }
}




void MainWindow::on_tableWidget_2_clicked(const QModelIndex &index)
{
    emit setShowType(16);
    showList_Type = 16;//TableWidget显示 标志位为16
//    update()是更新这个控件
//    viewport()->update()是更新这个控件里面的内容
    ui->treeWidget->viewport()->update();//更新控件的内容  updata只更新控件

     qDebug()<<"进制数按钮按下:    "<<showList_Type;
}
